package org.budo.filestore.buffer;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import org.budo.filestore.api.DownloadRequest;
import org.budo.filestore.api.FileStore;
import org.budo.filestore.api.UploadRequest;
import org.budo.filestore.api.UploadResponse;
import org.budo.filestore.impl.DefaultUploadRequest;
import org.budo.filestore.impl.DefaultUploadResponse;
import org.budo.support.lang.util.IoUtil;
import org.budo.support.slf4j.Slf4j;
import org.budo.support.spring.aop.util.AopUtil;
import org.slf4j.Logger;

/**
 * 上传文件时加一个缓冲区
 * 
 * @author lmw
 */
public class BufferFileStore extends AbstractBufferFileStore {
    private static final Logger log = Slf4j.getLogger();

    public BufferFileStore() {}

    public BufferFileStore(FileStore fileStore) {
        this.setFileStore(fileStore);
    }

    protected BufferFileStore _this() {
        return AopUtil.proxy(this);
    }

    public UploadResponse upload(final UploadRequest request) {
        // 加入缓冲区
        final String contentUrl = request.getContentUrl();
        final byte[] byteArray = _this().uploadRequestToByteArray(request);

        this.getBufferMap().put(contentUrl, byteArray);

        // 异步上传
        _this().submitUpload(contentUrl, byteArray);

        // 直接返回成功
        return new DefaultUploadResponse(true);
    }

    protected void submitUpload(final String contentUrl, final byte[] byteArray) {
        this.executorService().submit(new Runnable() {
            public void run() {
                DefaultUploadRequest request = new DefaultUploadRequest(contentUrl, byteArray);
                UploadResponse response = BufferFileStore.super.upload(request);
                if (null == response.getSuccess() || !response.getSuccess()) {
                    log.error("#55 getExecutorService upload error, request=" + request + ", response=" + response);
                    return;
                }

                // 上传成功后从缓冲区清除
                BufferFileStore.this.getBufferMap().remove(contentUrl);
            }
        });
    }

    protected byte[] uploadRequestToByteArray(final UploadRequest request) {
        return IoUtil.toByteArray(request.getInputStream());
    }

    @Override
    public InputStream downloadStream(DownloadRequest request) {
        byte[] bufferData = this.getBufferMap().get(request.getContentUrl());
        if (null != bufferData) {
            return new ByteArrayInputStream(bufferData);
        }

        return super.downloadStream(request);
    }
}
